AEL COMPUTER SCIENCE ENCYCLOPEDIA
Reverse Engineering (Week 1 C) · Sovereign Documentation
⚑ 100% SILICON & COGNITIVE DEPTH
AYMAN ELMASRY
Computational Creative Director · AI Prompt Engineer
Founder of Ayman Elmasry LLC
πŸ”’ ⚑ AEL Sovereign Seal (Active Verification)
{
  "ael_seal": "AEL CS Encyclopedia β€” Β© Ayman Elmasry",
  "owner": "Ayman Elmasry",
  "legal_entities": [
    "Ayman Elmasry LLC (UAE)",
    "Ayman Elmasry Advertising & Marketing (Egypt)"
  ],
  "section": "05_Practical_Reverse_Eng (Week 1 C)",
  "syllabus_source": "Harvard CS50x (Practical Reverse Engineering)",
  "methodology": "8-Stage Sub-Silicon Execution Paradigm",
  "system_version": "v3.0"
}

πŸ›οΈ Binary Forensics & Architectural Inspection

In this dedicated Practical Reverse Engineering wing, we transcend the conventional developer workflow of merely authoring and compiling hello.c. Here, we adopt the exacting rigor of a Binary Forensic Investigator, dissecting the resultant binary artifacts (hello.o and hello) to analyze precisely how they are parsed and executed by the bare-metal CPU and operating system kernel.

===================================================================================
                       THE REVERSE ENGINEERING TOOLBOX
===================================================================================

  [ Executable Binary: ./hello ]
            β”‚
            β”œβ”€β–Ί $ strings hello    ──> Extracts ASCII Literals ("hello, world")
            β”œβ”€β–Ί $ nm hello         ──> Inspects Symbol Table (_main, _printf)
            β”œβ”€β–Ί $ objdump -d hello ──> Disassembles Machine Code to Assembly
            └─► $ strace / dtruss  ──> Traces Kernel System Calls (write)

===================================================================================

πŸ”¬ The Analytical Disassembly Suite

1. Extracting Static ASCII Assets (The strings Command)

When a C source file is transformed into machine code, where exactly does the literal string "hello, world\n" reside? Static ASCII text strings (String Literals) are archived within a specialized section of the compiled binary image known as the Read-Only Data Section (.rodata - Read-Only Data). By deploying the strings utility, we can scan the raw binary file to extract all human-readable character sequences without executing the underlying code:

$ strings hello
...
hello, world
What's your name? 
hello, %s
...

2. Inspecting the Symbol Table (The nm Command)

An executable binary houses a comprehensive Symbol Table (Symbol Table), mapping function identifiers to exact physical memory offsets. The nm diagnostic tool identifies internal function declarations (e.g., main) alongside dynamically linked external dependencies (e.g., printf and get_string):

$ nm hello
0000000100003f50 T _main
                 U _printf
                 U _get_string

3. Disassembling Machine Code to Assembly (The objdump Command)

Reverse-translates raw binary opcode sequences (0s & 1s) back into human-readable Assembly language mnemonics:

$ objdump -d hello
hello:  file format Mach-O 64-bit x86-64

Disassembly of section __TEXT,__text:
_main:
100003f50: 55                    pushq %rbp
100003f51: 48 89 e5              movq  %rsp, %rbp
100003f54: 48 8d 3d 55 00 00 00  leaq  85(%rip), %rdi  # loading "hello, world" string
100003f5b: e8 12 00 00 00        callq _printf
100003f60: 31 c0                 xorl  %eax, %eax
100003f62: 5d                    popq  %rbp
100003f63: c3                    retq

βš™οΈ Tracing Kernel System Calls (Syscalls)

In high-level systems architecture, printf is merely an elegant user-space wrapper. The physical CPU architecture possesses no native instruction for printing characters to a physical monitor. This is where Kernel System Calls (Syscalls) bridge the gap.

===================================================================================
                       KERNEL SYSTEM CALL PATHWAY
===================================================================================

  [ Application: printf("hello, world\n") ]
            β”‚
            β–Ό
  [ C Standard Library: libc (Buffers output) ]
            β”‚
            β–Ό  (User Mode -> Kernel Mode Switch)
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ [ OS Kernel Call: write(1, "hello, world\n", 13) ]     β”‚ ──> Writes to File Descriptor 1 (stdout)
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
  [ Hardware Device / Terminal Display ]

===================================================================================

πŸ’‘ Deconstructing the Kernel Output Pathway

When printf("hello, world\n") is executed, the C Standard Library issues a formal request to the Operating System Kernel via an explicit system call named write.

On Linux Environments (strace): Executing strace ./hello intercepts the kernel trap, logging the explicit operational arguments: write(1, "hello, world\n", 13) = 13.

On macOS Environments (dtruss): Utilizing sudo dtruss ./hello demonstrates that the application requests the OS kernel to push exactly 13 bytes (the length of the string plus the \n character) into File Descriptor 1 (File Descriptor 1), representing the standard output stream stdout.